package com.eugeneMa.service.impl;

import com.eugeneMa.common.Constant;
import com.eugeneMa.dao.ClassTimeDao;
import com.eugeneMa.dao.UserInfoDao;
import com.eugeneMa.entity.ClassTime;
import com.eugeneMa.entity.ClassTimePlan;
import com.eugeneMa.entity.Result;
import com.eugeneMa.entity.UserInfo;
import com.eugeneMa.enumEntity.ClassTimePlanTypeEnum;
import com.eugeneMa.enumEntity.DateFormatEnum;
import com.eugeneMa.enumEntity.ErrorMsg;
import com.eugeneMa.service.inter.ClassTimeService;
import com.eugeneMa.util.DateUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 学习铃Service
 *
 * @author Eugenema
 * @date 2022/3/31 15:29
 */
@Service
public class ClassTimeServiceImpl implements ClassTimeService {
    /** 日志 */
    private Logger logger = Logger.getLogger(ClassTimeServiceImpl.class);
    /** 课时表Dao */
    @Autowired
    ClassTimeDao classTimeDao;
    /** 用户表Dao */
    @Autowired
    UserInfoDao userInfoDao;

    /**
     * 获取用户的所有课时表
     *
     * @author Eugenema
     * @date 2022/3/31 15:30
     *
     * @param userId 用户ID
     *
     * @return 结果集
     **/
    @Override
    public Result getClassTimeByUserId (Integer userId) {
        //校验用户是否存在
        UserInfo userInfo = userInfoDao.queryUserById(userId);
        if (userInfo == null) {
            return new Result(false, null, ErrorMsg.USER_NO_EXISTS);
        }

        //获取所有课时表
        List<ClassTime> classTimes = classTimeDao.queryClassTimeByUserId(userId);
        if (classTimes == null || classTimes.size() < 0) {
            return new Result(false, null, ErrorMsg.RESULT_NULL);
        }
        return new Result(true, classTimes, null);
    }

    /**
     * 获取课时表计划
     *
     * @param classTimeId 课时表ID
     *
     * @author Eugenema
     * @date 2022/3/31 23:21
     *
     * @return 结果集
     **/
    @Override
    public Result getClassTimePlan (Integer classTimeId) {
        //获取课时表
        ClassTime classTime = classTimeDao.queryClassTimeById(classTimeId);
        if (classTime == null) {
            return new Result(false, null, ErrorMsg.CLASSTIME_NO_EXISTS);
        }

        /** 返回结果 */
        List<Object> resultData = new ArrayList<>();
        /** 预备铃，格式：HHmm */
        List<String> readyTimes = new ArrayList<>();
        /** 上课铃，格式：HHmm */
        List<String> goClassTimes = new ArrayList<>();
        /** 下课铃，格式：HHmm */
        List<String> afterClassTimes = new ArrayList<>();
        /** 课时表计划 */
        List<ClassTimePlan> classTimePlanList = new ArrayList<>();


        /** 午休开启标志：午休时长 > 休息时长 */
        Boolean noonBreakFlag = classTime.getNoonBreakMinutes() > classTime.getRestMinutes();
        /** 大课间节点 */
        List<Integer> bigBreakNode = new ArrayList<>();
        /** 开始时间 */
        Calendar startTime = Calendar.getInstance();

        //预备铃生成
        if (Constant.PUBLIC_YES.equals(classTime.getReadyBell())) {
            //初始化开始时间
            startTime.setTime(classTime.getStartTime());
            //上课时间 - 休息时长
            startTime.add(Calendar.MINUTE, -classTime.getRestMinutes());

            readyTimes.add(DateUtil.dateToString(startTime.getTime(), DateFormatEnum.HOURMINUTE_NOSPLIT));
            classTimePlanList.add(new ClassTimePlan("预备铃", startTime.getTime(), null, ClassTimePlanTypeEnum.READY));
        }

        //大课间节点生成
        //若有午休，下午的大课间会从下午第一节课重新开始计算，否则每两节课一个大课间
        if (Constant.PUBLIC_YES.equals(classTime.getBigBreak())) {
            if (noonBreakFlag) {
                for (int i = 2; i <= classTime.getForenoonNum(); i+=2) {
                    bigBreakNode.add(i);
                }
                for (int i = classTime.getForenoonNum() + 1; i <= classTime.getClassNum(); i+=2) {
                    bigBreakNode.add(i);
                }
            } else {
                for (int i = 2; i <= classTime.getClassNum(); i+=2) {
                    bigBreakNode.add(i);
                }
            }
        }

        //初始化开始时间
        startTime.setTime(classTime.getStartTime());

        /** 课时计划 */
        ClassTimePlan classTimePlan;

        //生成上下课时间
        for (int i = 1; i <= classTime.getClassNum(); i++) {
            classTimePlan = new ClassTimePlan();
            classTimePlan.setTitle(String.valueOf(i));
            classTimePlan.setTypeObject(ClassTimePlanTypeEnum.CLASSES);

            //上课时间
            goClassTimes.add(DateUtil.dateToString(startTime.getTime(), DateFormatEnum.HOURMINUTE_NOSPLIT));
            classTimePlan.setTimeStart(startTime.getTime());

            //下课时间：开始时间 + 学习时间
            startTime.add(Calendar.MINUTE, classTime.getLearnMinutes());
            afterClassTimes.add(DateUtil.dateToString(startTime.getTime(), DateFormatEnum.HOURMINUTE_NOSPLIT));
            classTimePlan.setTimeEnd(startTime.getTime());
            classTimePlanList.add(classTimePlan);

            //午休计算
            if (noonBreakFlag && i == classTime.getForenoonNum()) {
                //午休计划
                ClassTimePlan noonBreakPlan = new ClassTimePlan();
                noonBreakPlan.setTitle("午休");
                noonBreakPlan.setTimeStart(startTime.getTime());
                noonBreakPlan.setTypeObject(ClassTimePlanTypeEnum.REST);

                //午休的预备铃
                ClassTimePlan readyBellPlan = null;
                if (Constant.PUBLIC_YES.equals(classTime.getReadyBell())) {
                    readyBellPlan = new ClassTimePlan();
                    readyBellPlan.setTitle("预备铃");
                    readyBellPlan.setTypeObject(ClassTimePlanTypeEnum.READY);

                    //预备铃提前一个休息时长
                    startTime.add(Calendar.MINUTE, classTime.getNoonBreakMinutes() - classTime.getRestMinutes());

                    readyBellPlan.setTimeStart(startTime.getTime());

                    //计算午休结束时间，预备铃的时间 + 休息时长
                    startTime.add(Calendar.MINUTE, classTime.getRestMinutes());
                } else {
                    //计算午休结束时间
                    startTime.add(Calendar.MINUTE, classTime.getNoonBreakMinutes());
                }

                //添加午休计划
                noonBreakPlan.setTimeEnd(startTime.getTime());
                classTimePlanList.add(noonBreakPlan);

                //添加预备铃计划
                if (readyBellPlan != null) {
                    classTimePlanList.add(readyBellPlan);
                }
            } else {
                //课间计算
                if (bigBreakNode.size() > 0 && bigBreakNode.contains(i)) {
                    startTime.add(Calendar.MINUTE, classTime.getRestMinutes() * 2);
                } else {
                    startTime.add(Calendar.MINUTE, classTime.getRestMinutes());
                }
            }
        }

        //封装结果
        resultData.add(readyTimes);
        resultData.add(goClassTimes);
        resultData.add(afterClassTimes);
        resultData.add(classTimePlanList);

        return new Result(true, resultData, null);
    }

    /**
     * 新增课时表
     *
     * @param classTime 课时表对象
     *
     * @author Eugenema
     * @date 2022/4/4 15:27
     *
     * @return 新增的课时表
     **/
    @Override
    public Result addClassTime (ClassTime classTime) {
        //判断用户是否存在
        UserInfo userInfo = userInfoDao.queryUserById(classTime.getUserId());
        if (userInfo == null) {
            return new Result(false, null, ErrorMsg.USER_NO_EXISTS);
        }

        //检验是否有同名课时表
        Result judgeResult = designationSame(classTime.getUserId(), classTime.getDesignation());

        if (judgeResult.getFlag()) {
            return new Result(false, null, ErrorMsg.CLASSTIME_SAME_NAME);
        }

        //新增课时表
        classTimeDao.insertClassTime(classTime);
        return new Result(true, classTime,null);
    }

    /**
     * 根据id删除课时表
     *
     * @author Eugenema
     * @date 2022/4/8 16:02
     *
     * @param classTimeId 课时表ID
     * @param userId 用户ID
     *
     * @return 封装结果集
     **/
    @Override
    public Result deleteClassTimeById (Integer classTimeId, Integer userId) {
        //判断用户是否存在
        UserInfo userInfo = userInfoDao.queryUserById(userId);
        if (userInfo == null) {
            return new Result(false, null, ErrorMsg.USER_NO_EXISTS);
        }

        //判断课时表是否存在
        ClassTime classTime = classTimeDao.queryClassTimeById(classTimeId);
        if (classTime == null) {
            return new Result(false, null, ErrorMsg.CLASSTIME_NO_EXISTS);
        }

        //判断课时表是否为该用户所拥有
        if (!classTime.getUserId().equals(userId)) {
            return new Result(false, null, ErrorMsg.AUTH_LITTLE);
        }

        //删除课时表
        classTimeDao.deleteClassTimeById(classTimeId);
        return new Result(true, null, null);
    }

    /**
     * 判断课时表名称是否已存在
     *
     * @param userId      用户ID
     * @param designation 要校验的课时表名称
     *
     * @author Eugenema
     * @date 2022/4/16 12:54
     *
     * @return 校验结果，若已存在，返回true，异常或不存在返回false
     **/
    @Override
    public Result designationSame(Integer userId, String designation) {
        //判断用户是否存在
        UserInfo userInfo = userInfoDao.queryUserById(userId);
        if (userInfo == null) {
            return new Result(false, null, ErrorMsg.USER_NO_EXISTS);
        }

        //查找同名课时表
        ClassTime classTime = classTimeDao.queryClassTimeByDesignationAndUserId(designation, userId);
        if (classTime == null) {
            return new Result(false, null, null);
        }
        return new Result(true, null, ErrorMsg.CLASSTIME_SAME_NAME);
    }

    /**
     * 编辑课时表
     * 只能编辑自己的课时表
     *
     * @author Eugenema
     * @date 2022/4/16 13:43
     *
     * @param classTime 编辑后的课时表
     *
     * @return 若编辑成功，返回true，反之返回false
     **/
    @Override
    public Result editClassTime(ClassTime classTime) {
        //用户是否存在
        UserInfo userInfo = userInfoDao.queryUserById(classTime.getUserId());
        if (userInfo == null) {
            return new Result(false, null, ErrorMsg.USER_NO_EXISTS);
        }

        //要编辑的课时表是否存在
        ClassTime classTimeEdit = classTimeDao.queryClassTimeById(classTime.getId());
        if (classTimeEdit == null) {
            return new Result(false, null, ErrorMsg.CLASSTIME_NO_EXISTS);
        }

        //课时表名称是否同名（与之前不同才判断）
        if (!classTimeEdit.getDesignation().equals(classTime.getDesignation())) {
            Result result = designationSame(classTime.getUserId(), classTime.getDesignation());
            if (result.getFlag()) {
                return new Result(false, null, ErrorMsg.CLASSTIME_SAME_NAME);
            }
        }

        //删除原课时表
        classTimeDao.deleteClassTimeById(classTime.getId());

        //新增课时表
        classTimeDao.insertClassTime(classTime);
        return new Result(true, classTime, null);
    }
}
